#include "facefeaturetool.h"
#include <QDebug>
#include <vector>
#include <QFile>

// 初始化静态成员
FaceFeatureTool *FaceFeatureTool::m_instance = nullptr;

FaceFeatureTool::FaceFeatureTool()
    : m_faceEngine(nullptr), m_initialized(false)
{
    init();
}

FaceFeatureTool::~FaceFeatureTool()
{
    if (m_faceEngine)
    {
        delete m_faceEngine; // 释放人脸引擎对象
        m_faceEngine = nullptr;
    }
    m_initialized = false; // 重置初始化状态
    qInfo() << "人脸特征工具资源已释放";
}

FaceFeatureTool *FaceFeatureTool::getInstance()
{
    if (!m_instance)
    {
        m_instance = new FaceFeatureTool();
    }
    return m_instance;
}

void FaceFeatureTool::releaseInstance()
{
    if (m_instance)
    {
        delete m_instance;
        m_instance = nullptr;
    }
}

bool FaceFeatureTool::init()
{
    if (m_initialized)
    {
        qWarning() << "人脸特征工具已初始化";
        return true;
    }
    qDebug() << "[FaceFeatureTool] 开始初始化，准备加载模型...";

    try {
        // 1. 验证模型文件是否存在（关键：文件路径错误会导致加载阻塞/失败）
        QString fdModelPath = "C:/SeetaFace/bin/model/fd_2_00.dat";
        QString pdModelPath = "C:/SeetaFace/bin/model/pd_2_00_pts5.dat";
        QString frModelPath = "C:/SeetaFace/bin/model/fr_2_10.dat";

        QFile fdFile(fdModelPath);
        if (!fdFile.exists()) { qDebug() << "[ERROR] 人脸检测模型不存在：" << fdModelPath; return false; }
        QFile pdFile(pdModelPath);
        if (!pdFile.exists()) { qDebug() << "[ERROR] 关键点检测模型不存在：" << pdModelPath; return false; }
        QFile frFile(frModelPath);
        if (!frFile.exists()) { qDebug() << "[ERROR] 人脸识别模型不存在：" << frModelPath; return false; }
        qDebug() << "[FaceFeatureTool] 模型文件存在，开始创建模型配置...";

        // 2. 初始化模型配置（避免静态变量导致的线程安全问题）
        ModelSetting FD_model(fdModelPath.toLocal8Bit().data(), SEETA_DEVICE_AUTO);
        ModelSetting PD_model(pdModelPath.toLocal8Bit().data(), SEETA_DEVICE_AUTO);
        ModelSetting FR_model(frModelPath.toLocal8Bit().data(), SEETA_DEVICE_AUTO);
        qDebug() << "[FaceFeatureTool] 模型配置创建完成，开始初始化引擎...";

        // 3. 创建人脸引擎（卡死大概率发生在这里）
        if (m_faceEngine) delete m_faceEngine; // 防止重复创建
        m_faceEngine = new FaceEngine(FD_model, PD_model, FR_model);
        qDebug() << "[FaceFeatureTool] 引擎创建完成，验证引擎状态...";

        // 4. 验证引擎是否有效（部分版本需要显式初始化）
        if (!m_faceEngine) { qDebug() << "[ERROR] 引擎创建失败（空指针）"; return false; }

        m_initialized = true;
        qDebug() << "[FaceFeatureTool] 初始化成功！";
        return true;
    } catch (const std::exception& e) {
        qDebug() << "[ERROR] 初始化异常：" << e.what();
        return false;
    } catch (...) {
        qDebug() << "[ERROR] 初始化未知异常";
        return false;
    }
}

bool FaceFeatureTool::faceComparison(QByteArray employeePhoneData,QByteArray attendPhotoData)
{
    // 将字节数组数据转换为OpenCV的Mat对象
    // 1. 处理员工人脸数据
    cv::Mat employeeMat = cv::imdecode(std::vector<uchar>(employeePhoneData.begin(), employeePhoneData.end()), cv::IMREAD_COLOR);
    if (employeeMat.empty()) {
        qDebug() << "员工人脸图片解码失败";
        return false;
    }

    // 2. 处理待比对人脸数据
    cv::Mat attendMat = cv::imdecode(std::vector<uchar>(attendPhotoData.begin(), attendPhotoData.end()), cv::IMREAD_COLOR);
    if (attendMat.empty()) {
        qDebug() << "待比对人脸图片解码失败";
        return false;
    }

    // 转换为SeetaImageData格式
    SeetaImageData employeeSeetaData;
    employeeSeetaData.data = employeeMat.data;
    employeeSeetaData.width = employeeMat.cols;
    employeeSeetaData.height = employeeMat.rows;
    employeeSeetaData.channels = employeeMat.channels();

    SeetaImageData attendSeetaData;
    attendSeetaData.data = attendMat.data;
    attendSeetaData.width = attendMat.cols;
    attendSeetaData.height = attendMat.rows;
    attendSeetaData.channels = attendMat.channels();

    float similarity =  m_faceEngine->Compare(employeeSeetaData, attendSeetaData);
    // 判断相似度是否达到阈值（通常建议0.7-0.8，根据实际需求调整）
    const float THRESHOLD = 0.75f;
    qDebug() << "人脸比对相似度: " << similarity;
    return (similarity >= THRESHOLD);
}
